package com.minisoft.ai;// 建议dashscope SDK的版本 >= 2.15.0
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.dashscope.app.*;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import io.reactivex.Flowable;// 流式输出
import lombok.extern.slf4j.Slf4j;

import java.util.List;

// 智能体应用调用实现流式输出结果
@Slf4j
public class Main {
    public static void streamCall() throws NoApiKeyException, InputRequiredException {
        ApplicationParam param = ApplicationParam.builder()
                // 若没有配置环境变量，可用百炼API Key将下行替换为：.apiKey("sk-xxx")。但不建议在生产环境中直接将API Key硬编码到代码中，以减少API Key泄露风险。
                .apiKey("sk-837018ca105a4629ac23b8545d3c844a")
                .appId("e7e7091a485e4f22ac46e46623e97ff8")
//                .appId("64a1c6a0457340fdbd58de840e105c79")
                .prompt("大湾区华发项目的最新购房政策")//写个快速排序代码，使用java
//                .sessionId("oiaXF5KSqa5ctvrmD5kZaxiLE6xI")
//                .prompt("介绍一下又一城")
//                .parameter("flow_stream_mode","full_thoughts")
                .parameter("flow_stream_mode","full_thoughts")
//                .incrementalOutput(true)// 增量输出,[如果打开会有多次回调]
                .hasThoughts(true) // 工作流应用实现流式输出需要设置此参数为true，输出结果在thoughts字段中查看
                .build();
        Application application = new Application();
        // .streamCall（）：流式输出内容
        log.info("开始调用智能体应用");
        Flowable<ApplicationResult> result = application.streamCall(param);
        StringBuilder previousReasoningContent = new StringBuilder();
        StringBuilder previousResultContent = new StringBuilder();
        result.blockingForEach(data -> {
            if (data.getOutput().getThoughts() != null) {
                data.getOutput().getThoughts().forEach(thought -> {
                    JSONObject response = JSONUtil.parseObj(thought.getResponse());
                    String nodeType = response.getStr("nodeType");//LLM
                    String nodeName = response.getStr("nodeName");
//                    System.out.printf("%s\n",data.getOutput().getThoughts());// 处理输出只展示thoughts字段
                    if (nodeName.contains("输出节点")) {
//                        ThreadUtil.sleep(1000);
//                        System.out.printf("%s\n",thought);// 处理输出只展示thoughts字段
                        JSONObject nodeResult = response.getJSONObject("nodeResult");
                        if (nodeResult != null) {
                            String reasoningContent = nodeResult.getStr("reasoningContent");
                            String resultText = nodeResult.getStr("result");
                            if (StrUtil.isNotBlank(resultText)) {
                                if (previousResultContent.length() == 0) {
                                    System.out.println();
                                    log.info("开始回答");
                                }
                                String newDelta = resultText.substring(previousResultContent.length());
//                                    log.info("回答内容：{}", newDelta);
                                System.out.print(newDelta);
                                previousResultContent.append(newDelta);
                            } else {
                                if (previousReasoningContent.length() == 0) {
                                    log.info("开始推理过程");
                                }
                                String newDelta = reasoningContent.substring(previousReasoningContent.length());
//                                    log.info("推理过程：{}", newDelta);
                                System.out.print(newDelta);
                                previousReasoningContent.append(newDelta);
                            }
                        }
                    }
                });
            }
        });
        System.out.println("结束");
    }
    public static void main(String[] args) {
        try {
            streamCall();
        } catch (ApiException | NoApiKeyException | InputRequiredException e) {
            System.out.printf("Exception: %s", e.getMessage());
            System.out.println("请参考文档：https://help.aliyun.com/zh/model-studio/developer-reference/error-code");
        }
        System.exit(0);
    }
}